package com.neusoft.neuiotms.dcom.service.incident.impl;

import java.util.Date;

import javax.persistence.EntityNotFoundException;
import javax.transaction.Transactional;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.activiti.enums.WorkOrderStatus;
import com.neusoft.bizcore.activiti.service.ProcessInstanceService;
import com.neusoft.bizcore.auth.common.bean.UserBean;
import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.neuiotms.dcom.converter.incident.IncidentConfirmConverter;
import com.neusoft.neuiotms.dcom.dto.change.ChangeRegistrationDTO;
import com.neusoft.neuiotms.dcom.dto.incident.IncidentConfirmDTO;
import com.neusoft.neuiotms.dcom.dto.incident.IncidentRegisterDTO;
import com.neusoft.neuiotms.dcom.dto.problem.ProblemRegistrationDTO;
import com.neusoft.neuiotms.dcom.model.enums.IncidentHandleOperation;
import com.neusoft.neuiotms.dcom.model.incident.IncidentConfirm;
import com.neusoft.neuiotms.dcom.repository.incident.IncidentConfirmRepository;
import com.neusoft.neuiotms.dcom.service.change.ChangeRegistrationService;
import com.neusoft.neuiotms.dcom.service.incident.IncidentConfirmService;
import com.neusoft.neuiotms.dcom.service.incident.IncidentRegisterService;
import com.neusoft.neuiotms.dcom.service.problem.ProblemRegistrationService;

/**
 * @author WYS
 * @date 2020年8月18日 下午2:06:12
 */
@Service
public class IncidentConfirmServiceImpl implements IncidentConfirmService {
    @Autowired
    private IncidentConfirmRepository incidentConfirmRepository;
    @Autowired
    private IncidentConfirmConverter incidentConfirmConverter;
    @Autowired
    private ProcessInstanceService processInstanceService;
    @Autowired
    private ProblemRegistrationService problemRegistrationService;
    @Autowired
    private ChangeRegistrationService changeRegistrationService;
    @Autowired
    private IncidentRegisterService incidentRegisterService;

    @Override
    @Transactional
    public IncidentConfirmDTO create(final IncidentConfirmDTO dto, final UserBean user) {
        this.processInstanceService.setGlobalVariable(dto.getTaskId(), "incidentHandleOperation",
                dto.getOperation());
        if (dto.getOperation().name().equals(IncidentHandleOperation.question.name())) {
            // 调用问题接口
            final IncidentRegisterDTO incidentDTO = this.incidentRegisterService.findByWorkNum(dto.getWorkOrderNum());
            if (incidentDTO != null) {
                final ProblemRegistrationDTO problemDTO = new ProblemRegistrationDTO();
                problemDTO.setApplicant(incidentDTO.getApplyUserName());
                problemDTO.setApplicationType(incidentDTO.getApplyType());
                problemDTO.setCiCode(incidentDTO.getObjCode());
                problemDTO.setCiName(incidentDTO.getObjName());
                problemDTO.setCiId(incidentDTO.getObjId());
                problemDTO.setContactInformation(incidentDTO.getCommunicationNumber());
                problemDTO.setExecutorCode(incidentDTO.getDispatchUserCode());
                problemDTO.setExecutor(incidentDTO.getDispatchUserName());
                problemDTO.setInfluenceCoverage(incidentDTO.getCoverageInfluence());
                problemDTO.setPriority(incidentDTO.getPriority());
                problemDTO.setUrgencyDegree(incidentDTO.getUrgency());
                problemDTO.setRegistrantCode(incidentDTO.getRegisterUserCode());
                problemDTO.setRegistrant(incidentDTO.getRegisterUserName());
                problemDTO.setSource("INCIDENT_STUDY");
                problemDTO.setStatus(WorkOrderStatus.temporary.name());
                problemDTO.setTitle(incidentDTO.getName());
                problemDTO.setApplicationTime(new Date());
                problemDTO.setDescription(incidentDTO.getDescription());

                this.problemRegistrationService.create(problemDTO, user);
            }
        }

        if (dto.getOperation().name().equals(IncidentHandleOperation.change.name())) {
            // 调用变更接口
            final IncidentRegisterDTO incidentDTO = this.incidentRegisterService.findByWorkNum(dto.getWorkOrderNum());
            if (incidentDTO != null) {
                final ChangeRegistrationDTO changeDTO = new ChangeRegistrationDTO();
                changeDTO.setApplicant(incidentDTO.getApplyUserName());
                changeDTO.setApplicationType(incidentDTO.getApplyType());
                changeDTO.setCiId(incidentDTO.getObjCode());
                changeDTO.setCiCode(incidentDTO.getObjCode());
                changeDTO.setCiName(incidentDTO.getObjName());
                changeDTO.setContactInformation(incidentDTO.getCommunicationNumber());
                changeDTO.setExecutorCode(incidentDTO.getDispatchUserCode());
                changeDTO.setExecutor(incidentDTO.getDispatchUserName());
                changeDTO.setInfluenceCoverage(incidentDTO.getCoverageInfluence());
                changeDTO.setPriority(incidentDTO.getPriority());
                changeDTO.setUrgencyDegree(incidentDTO.getUrgency());
                changeDTO.setRegistrantCode(incidentDTO.getRegisterUserCode());
                changeDTO.setRegistrant(incidentDTO.getRegisterUserName());
                changeDTO.setSource("INCIDENT_CHANGE");
                changeDTO.setStatus(WorkOrderStatus.temporary.name());
                changeDTO.setTitle(incidentDTO.getName());
                changeDTO.setApplicationTime(new Date());
                changeDTO.setDescription(incidentDTO.getDescription());

                this.changeRegistrationService.create(changeDTO, user);
            }
        }

        // 查询当前workNum和TaskId下是否存在记录
        final IncidentConfirm oldModel = this.incidentConfirmRepository.findByWorkNumAndTaskId(
                dto.getWorkOrderNum(), dto.getTaskId());
        if (oldModel == null) { // 如果不存在新增
            dto.setId(null);
        }

        final IncidentConfirm model = this.incidentConfirmConverter.toModel(dto);
        this.incidentConfirmRepository.save(model);

        // 完成节点
        this.processInstanceService.complete(dto.getWorkOrderNum(), dto.getTaskId(), user);

        return this.incidentConfirmConverter.toDTO(model);
    }

    @Override
    public IncidentConfirmDTO detail(final String workOrderNum, final String taskId,
            final UserBean user) {
        IncidentConfirm model = null;
        try {
            if (StringUtils.isNotBlank(workOrderNum) && !"NULL".equals(taskId)) {
                model = this.incidentConfirmRepository.findByWorkNumAndTaskId(workOrderNum, taskId);
                if (model == null) {
                    // 获取前一节点的TaskID
                    final String fromProcessTaskId = this.processInstanceService.getLastTaskId(taskId, user);
                    if (fromProcessTaskId == null) {
                        return new IncidentConfirmDTO();
                    } else {
                        model = this.incidentConfirmRepository.findByWorkNumAndTaskId(workOrderNum,
                                fromProcessTaskId);
                    }
                }
            } else if ("NULL".equals(taskId)) {
                model = this.incidentConfirmRepository.findByWorkNum(workOrderNum);
            }
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND,
                    new Object[] {workOrderNum },
                    new Object[] {taskId });
        }
        return this.incidentConfirmConverter.toDTO(model);
    }

    @Override
    public IncidentConfirmDTO findByWorkNumAndTaskId(final String workNum, final String taskId) {
        final IncidentConfirm model = this.incidentConfirmRepository.findByWorkNumAndTaskId(workNum, taskId);
        return this.incidentConfirmConverter.toDTO(model);
    }

    @Override
    public void deleteByWorkNum(final String workNum) {
        this.incidentConfirmRepository.deleteByWorkNum(workNum);
    }

}
